package com.moleq.mgpos.activities;

import java.io.File;
import java.io.FileWriter;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.xmlpull.v1.XmlSerializer;

import android.app.ProgressDialog;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Xml;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.RadioButton;
import android.widget.TextView;

import com.moleq.base.MoleQBaseActivity;
import com.moleq.base.MoleQBaseDialog;
import com.moleq.device.DeviceManager;
import com.moleq.dialog.DateSettingSelectionDialog;
import com.moleq.dialog.InputDateInfoDialog;
import com.moleq.dialog.MessageBox;
import com.moleq.dialog.MessageDialog;
import com.moleq.dialog.NetworkStationDialog;
import com.moleq.dialog.MessageDialog.OnClickMessageListener;
import com.moleq.logic.DialogManager;
import com.moleq.logic.PosPrinter;
import com.moleq.logic.Report;
import com.moleq.models.GlobalInfo;
import com.moleq.models.NetworkSetting;
import com.moleq.models.PosSetting;
import com.moleq.models.TextAndCheckBox;
import com.moleq.network.Constant;
import com.moleq.network.RemoteReportHandler;
import com.moleq.network.ReportCallback;
import com.moleq.network.ReportCreator;
import com.moleq.service.NetWorkSettingService;
import com.moleq.service.ServiceManager;
import com.moleq.util.MoleQUtil;

public class NetworkReportActivity extends MoleQBaseActivity {

	private static final int RECEIVEING = 0;
	private static final int FINISH = 1;
	private static final int UPDATE_STATE = 2;
	private TextView tv_content;
	private EditText et_startDate, et_endDate;
	private Button btn_go, btn_print, btn_exit,btn_export;
	private CheckBox cb_fixTotal, cb_functionKey, cb_department, cb_plu, cb_group, cb_plu_tare;
	private List<TextAndCheckBox> listItem = null;
	private Calendar cal = Calendar.getInstance();
	private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

	private NetWorkSettingService mNetWorkSettingService;
	private NetworkStationDialog mNetworkStationDialog = null;
	private String startDate, endDate;
	private RemoteReportHandler remoteRptSvr = new RemoteReportHandler();
	private ReportCreator creator = new ReportCreator();
	private int index = -1;
	private String singleRptContent = "", ip = "", totalContent = "";
	private int station;
	private String equalStr = "\n===============================================";
	private RadioButton rbtn_collection, rbtn_consolidation;
	public HashMap<String, Report> respots = new HashMap<String, Report>();
	public List<String> showReportName = new ArrayList<String>();
	private DateSettingSelectionDialog mdssDialog;
	private InputDateInfoDialog ididDialog;
	private static MessageDialog mMessageDialog ;
	private static ProgressDialog mNetworkReportExport;
	
	private Handler mHandler = new Handler() {

		@Override
		public void handleMessage(Message msg) {
			switch (msg.what) {
			case RECEIVEING:
				mNetworkStationDialog.setState(NetworkStationDialog.BUSY);
				break;
			case FINISH:
				mNetworkStationDialog.setState(NetworkStationDialog.REPORT_READY);
				break;
			case UPDATE_STATE:
				mNetworkStationDialog.refresh();
				break;
			default:
				break;
			}
		}
	};
	

	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.activity_network_report);

		tv_content = (TextView) findViewById(R.id.tv_content);
		btn_go = (Button) findViewById(R.id.btn_go);
		btn_print = (Button) findViewById(R.id.btn_print);
		btn_exit = (Button) findViewById(R.id.btn_exit);
		btn_export = (Button) findViewById(R.id.btn_export);
		cb_fixTotal = (CheckBox) findViewById(R.id.cb_fixTotal);
		cb_functionKey = (CheckBox) findViewById(R.id.cb_functionKey);
		cb_department = (CheckBox) findViewById(R.id.cb_department);
		cb_plu = (CheckBox) findViewById(R.id.cb_plu);
		cb_group = (CheckBox) findViewById(R.id.cb_group);
		cb_plu_tare = (CheckBox) findViewById(R.id.cb_plu_tare);
		et_startDate = (EditText) findViewById(R.id.et_startDate);
		rbtn_collection = (RadioButton) findViewById(R.id.rbtn_collection);
		rbtn_consolidation = (RadioButton) findViewById(R.id.rbtn_consolidation);

		sdf = new SimpleDateFormat("yyyy-MM-dd");
		et_startDate.setText(sdf.format(cal.getTime()));
		et_startDate.setOnClickListener(onClickListener);
		btn_go.setOnClickListener(onClickListener);
		btn_print.setOnClickListener(onClickListener);
		btn_exit.setOnClickListener(onClickListener);
		btn_export.setOnClickListener(onClickListener);
		
		mNetWorkSettingService = ServiceManager.getInstance().mNetWorkSettingService;
		remoteRptSvr = new RemoteReportHandler();
		creator = new ReportCreator();
		remoteRptSvr.setReportCreator(creator, mReportCallback);

		initReports();
		
		mdssDialog = new DateSettingSelectionDialog(this);
		ididDialog = new InputDateInfoDialog(this, this);
		PosSetting item = ServiceManager.getInstance().mPosSettingService.Find();
		if(item == null){
			GlobalInfo.getInstance().calendar_type = false;
		}else{
			GlobalInfo.getInstance().calendar_type = item.isCalendarType();
		}
		DeviceManager.getInstance().setPrinter(new PosPrinter());
		DeviceManager.getInstance().printer.setEnable(true);
		
		startDate = MoleQUtil.fixDateTime2(String.valueOf(et_startDate.getText()), "yyyyMMdd", "yyyy-MM-dd");
		endDate = MoleQUtil.fixDateTime2(String.valueOf(et_startDate.getText()), "yyyyMMdd", "yyyy-MM-dd");

		mNetworkReportExport = new ProgressDialog(NetworkReportActivity.this);
		mMessageDialog  =  new MessageDialog(NetworkReportActivity.this);
		mNetworkReportExport.setTitle("");
		mNetworkReportExport.setMessage("Export Data...");
		mNetworkReportExport.setProgressStyle(ProgressDialog.STYLE_SPINNER);
	}

	public void initReports() {
		respots.put(Constant.RPT_FIXED_TOTAL, new Report("Fixed Total"));
		respots.put(Constant.RPT_DEPARTMENT, new Report("Department"));
		respots.put(Constant.RPT_FUNCTION, new Report("Function"));
		respots.put(Constant.RPT_SCANNING_ITEM, new Report("Scanning Item"));
		respots.put(Constant.RPT_GROUP, new Report("Group"));
		respots.put(Constant.RPT_PLU_MULTI_TARE, new Report("PLU - Multi.Tare"));

	}

	public void resetReprots() {
		if (respots != null) {
			Iterator<Entry<String, Report>> iter = respots.entrySet().iterator();
			while (iter.hasNext()) {
				Map.Entry entry = (Map.Entry) iter.next();
				// Object key = entry.getKey();
				Report val = (Report) entry.getValue();
				val.reset();
			}
		}
	}

	@Override
	public void onReturnValue(int what, Object obj) {
		switch (what) {
		case R.id.btn_ok:
			Thread thread = new Thread(){
				@Override
				public void run(){
					
					resetReprots();
					totalContent = "";
					
					Message recMsg = new Message();
					recMsg.what = RECEIVEING;
					mHandler.sendMessage(recMsg);

					if (rbtn_collection.isChecked()) {
						for (int i = 0; i < listItem.size(); i++) {
							index = i;
							station = Integer.valueOf(listItem.get(i).getTag());
							ip = mNetWorkSettingService.FindIPByStn(station);

							if (!listItem.get(i).isCheck()) {
								continue;
							}
							
							System.out.println("access report ->" + ip);
							singleRptContent = "";
							String ls_RptContent = "";

							for (int j = 0; j < showReportName.size(); j++) {

								Report rpt = respots.get(showReportName.get(j));
								rpt.reset();
								remoteRptSvr.accessReport(ip, showReportName.get(j), startDate, endDate);
								if (listItem.get(i).isReportStare()) {
									ls_RptContent = rpt.toPrintReport();
									if (!ls_RptContent.equals("")) {
										ls_RptContent += "\n";
									}
									singleRptContent += rpt.getReportName(startDate) + ls_RptContent + rpt.getFooter(showReportName.get(j));
								}else {
									singleRptContent =  "Not Available";
								}
							}

							if (singleRptContent.length() > 0) {
								singleRptContent = "Station " + station + "\n" + singleRptContent;
								totalContent += singleRptContent + equalStr + "\n\n\n\n";
							}

						}
					} else if (rbtn_consolidation.isChecked()) {
						for (int i = 0; i < listItem.size(); i++) {
							index = i;
							station = Integer.valueOf(listItem.get(i).getTag());
							ip = mNetWorkSettingService.FindIPByStn(station);

							if (!listItem.get(i).isCheck()) {
								continue;
							}
							for (int j = 0; j < showReportName.size(); j++) {
								remoteRptSvr.accessReport(ip, showReportName.get(j), startDate, endDate);
							}
							totalContent = "";
							for (int j = 0; j < showReportName.size(); j++) {
								Report rpt = respots.get(showReportName.get(j));
								if(rpt.getmReportName().equals("Fixed Total")) rpt.calculateAverage();
								String content = "";
								content = rpt.toPrintReport();
								String singleRptContent = "";
								if (!content.equals("")) {
									content += "\n";
								}
								singleRptContent += rpt.getReportName(startDate) + content + rpt.getFooter(showReportName.get(j));
								totalContent += singleRptContent;
							}

						}
					}

					Message finishMsg = new Message();
					finishMsg.what = FINISH;
					mHandler.sendMessage(finishMsg);
				}
			};
			thread.start();
			
			
			break;
		case R.id.btn_report:

			tv_content.setText(totalContent);
			mNetworkStationDialog.dismiss();
			break;
		}
	}
	
	public void exportReport() throws Throwable {
		
			String time = MoleQUtil.getNow2();
			String filename = Constant.SDCARD_EXPORT;
			File newfile = new File(filename);
			if(!newfile.exists()) {
				if(!newfile.mkdirs()) {
				     return;
				}
			}
			
			if (mNetworkReportExport == null || mNetworkReportExport.isShowing())
				return;
				mNetworkReportExport.show();
//			if (newfile.isDirectory())
//				return;
//
//			if (!newfile.exists()) {
//				newfile.createNewFile();
//			}
			filename = filename+String.format(Constant.DATA_XML_FILE_NAME, time);
			FileWriter writer = new FileWriter(new File(filename));
			
			XmlSerializer serializer = Xml.newSerializer();
			serializer.setOutput(writer);
			serializer.startDocument("UTF-8", true);
			serializer.startTag(null,"NetReport");
			if (rbtn_collection.isChecked()) {
				serializer.attribute(null, "type", "collection");
			}else{
				serializer.attribute(null, "type", "consolidation");
			}
			//create time
			serializer.startTag(null,"CreateDatetime");
			serializer.text(MoleQUtil.fixDateTime2(time, "yyyy-MM-dd HH:mm:ss", "yyyyMMddHHmmss"));
			serializer.endTag(null,"CreateDatetime");
			
			//context		
			String ls_RptContent = "";
			resetReprots();
			for (int i = 0; i < listItem.size(); i++) {
				index = i;
				station = Integer.valueOf(listItem.get(i).getTag());
				ip = mNetWorkSettingService.FindIPByStn(station);

				if (!listItem.get(i).isCheck()) {
					continue;
				}
				
				
				if (rbtn_collection.isChecked()) {
					
					serializer.startTag(null,"Station");
					serializer.text(String.valueOf(station));
					serializer.endTag(null,"Station");
					
					for (int j = 0; j < showReportName.size(); j++) {
						
						Report rpt = respots.get(showReportName.get(j));
						rpt.reset();
						remoteRptSvr.accessReport(ip, showReportName.get(j), startDate, endDate);

						serializer.startTag(null,"Title");
						serializer.text(rpt.getmReportName());
						serializer.endTag(null,"Title");
						
						serializer.startTag(null,"Date");
						serializer.text(startDate);
						serializer.endTag(null,"Date");
						
						serializer.startTag(null,"Content");
						
						if (listItem.get(i).isReportStare()) {
							ls_RptContent = rpt.toPrintReport();
						}else {
							ls_RptContent =  "\n Not Available\n";
						}
						
						if (!ls_RptContent.equals("")) {
							ls_RptContent = ls_RptContent.substring(1,ls_RptContent.length());
						}
						
						String[] lines = ls_RptContent.split("\n");
						for (int k = 0; k < lines.length; k++) {
							serializer.startTag(null,"Line");
							serializer.text(lines[k]);
							serializer.endTag(null,"Line");
						}
						if (!rpt.getExportFooter(showReportName.get(j)).equals("")) {
							serializer.startTag(null,"Line");
							serializer.text(rpt.getExportFooter(showReportName.get(j)));
							serializer.endTag(null,"Line");
						}
						
						serializer.endTag(null,"Content");
					}
					
				}else{
					for (int j = 0; j < showReportName.size(); j++) {
						remoteRptSvr.accessReport(ip, showReportName.get(j), startDate, endDate);
					}
					totalContent = "";
					for (int j = 0; j < showReportName.size(); j++) {
						Report rpt = respots.get(showReportName.get(j));
//						rpt.reset();
						if(rpt.getmReportName().equals("Fixed Total")) rpt.calculateAverage();
						
						String content = "";
						content = rpt.toPrintReport();
						
						if (i+1 == listItem.size()) {
							
							serializer.startTag(null,"Title");
							serializer.text(rpt.getmReportName());
							serializer.endTag(null,"Title");
							
							serializer.startTag(null,"Date");
							serializer.text(startDate);
							serializer.endTag(null,"Date");
							
							serializer.startTag(null,"Content");

							if (!content.equals("")) {
								content = content.substring(1,content.length());
							}
							
							String[] lines = content.split("\n");
							for (int k = 0; k < lines.length; k++) {
								serializer.startTag(null,"Line");
								serializer.text(lines[k]);
								serializer.endTag(null,"Line");
							}
							
							serializer.endTag(null,"Content");
						}
					}
				}
				
			}
			serializer.endTag(null,"NetReport");
			serializer.endDocument();
			
			writer.flush();
			writer.close();
			
			 if (mNetworkReportExport != null && mNetworkReportExport.isShowing())
				mNetworkReportExport.dismiss();
			
			mMessageDialog.setMessage("Report data has been exported.");
			mMessageDialog.setOnClickMessageListener(mOnClickMessageListener);
			mMessageDialog.show();
	}

	private static  OnClickMessageListener mOnClickMessageListener = new OnClickMessageListener(){

		@Override
		public void onClickYes() {
		}

		@Override
		public void onClickNo() {
		
		}

		@Override
		public void onClickOK() {
			if (mMessageDialog != null && mMessageDialog.isShowing()) {
				mMessageDialog.dismiss();
			}
		}
		
	};
	
	private List<TextAndCheckBox> readValueFromSettings(List<NetworkSetting> settings) {
		List<TextAndCheckBox> value = new ArrayList<TextAndCheckBox>();

		if (settings == null || settings.size() <= 0) {
			return value;
		}
		for (int i = 0; i < settings.size(); i++) {
			TextAndCheckBox textAndCheckBox = new TextAndCheckBox();
			textAndCheckBox.setTag(String.valueOf(settings.get(i).getNs_station()));
			textAndCheckBox.setText("Station # " + settings.get(i).getNs_station());
			textAndCheckBox.setCheck(true);
			textAndCheckBox.setIp(settings.get(i).getNs_ip());
			value.add(textAndCheckBox);
		}
		return value;
	}

	public void ConvertLoaclData(String reportData) {

		String temp[] = reportData.split("\\|");
		String reportName = temp[0];
		for (int i = 1; i < temp.length; i++) {

			String item = temp[i];
			List<String> newStrings = MoleQUtil.parseSqlRecord(item.substring(1, item.length() - 1));

			String[] line = new String[newStrings.size()];

			for (int j = 0; j < newStrings.size(); j++) {
				String ls = newStrings.get(j);
//				String ls2 = ls.substring(0, 1);
//				if (ls2.equals("'")) {
//					ls = ls.substring(1, ls.length() - 1);
//				}
				line[j] = ls;
			}

			Report rpt = respots.get(reportName);
			rpt.sum(line);

		}
	}

	private ReportCallback mReportCallback = new ReportCallback() {

		@Override
		public void onFaild(String msg) {
			System.out.println("ReportCallback.onFaild ->" + msg);
			listItem.get(index).setState(false);
			listItem.get(index).setOnline(false);
			listItem.get(index).setReportStare(false);
			
			Message recMsg = new Message();
			recMsg.what = UPDATE_STATE;
			mHandler.sendMessage(recMsg);
		}

		@Override
		public void onCreate(String reportData) {
			System.out.println("ReportCallback.onCreate ->" + reportData);

			listItem.get(index).setState(true);
			listItem.get(index).setOnline(true);
			listItem.get(index).setReportStare(true);
			
			Message recMsg = new Message();
			recMsg.what = UPDATE_STATE;
			mHandler.sendMessage(recMsg);

			ConvertLoaclData(reportData);
		}
	};

	private OnClickListener onClickListener = new OnClickListener() {

		public void onClick(View v) {
			switch (v.getId()) {
			case R.id.btn_go:
				getCollectionReport();
				break;
			case R.id.btn_print:
				if (showReportName != null) {
					Report rpt = new Report("");
					String context = rpt.toPrintContent(totalContent);
					PosPrinter printer = (PosPrinter) DeviceManager.getInstance().printer;
					if (printer.getEnable() && !printer.isBusy()) {
						printer.onConnect();
						printer.print(context);
						printer.cutPaper();
						printer.onDisconnect();
					}
				}
				break;
			case R.id.btn_exit:
				MessageBox.show(NetworkReportActivity.this, getResources().getString(R.string.msg_exit_program), onClickMessageListener, MessageDialog.MESSAGE_BOX_YES_NO);
				break;
			case R.id.et_startDate:
				if (GlobalInfo.getInstance().calendar_type) {
					mdssDialog.show(R.id.et_startDate,et_startDate.getText().toString());
				}else{
					ididDialog.show(R.id.et_startDate,et_startDate.getText().toString());
				}
				break;
				
			case R.id.btn_export:
				
				if (!tv_content.getText().toString().equals("")) {
					MessageBox.show(NetworkReportActivity.this, "Do you want to export the report data?", mExportlistener, MessageDialog.MESSAGE_BOX_YES_NO);
					
				}
				
				break;
			}
		}

	};

	private OnClickMessageListener mExportlistener = new OnClickMessageListener() {

		@Override
		public void onClickYes() {

			try {
				
				exportReport();

			} catch (Throwable e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		}

		@Override
		public void onClickNo() {
		}

		@Override
		public void onClickOK() {

		}
	};
	public void getCollectionReport() {
		singleRptContent = "";
		totalContent = "";
		
		showReportName.clear();
		if (cb_fixTotal.isChecked())
			showReportName.add(Constant.RPT_FIXED_TOTAL);
		if (cb_functionKey.isChecked())
			showReportName.add(Constant.RPT_FUNCTION);
		if (cb_plu.isChecked())
			showReportName.add(Constant.RPT_SCANNING_ITEM);
		if (cb_department.isChecked())
			showReportName.add(Constant.RPT_DEPARTMENT);
		if (cb_group.isChecked())
			showReportName.add(Constant.RPT_GROUP);
		if (cb_plu_tare.isChecked())
			showReportName.add(Constant.RPT_PLU_MULTI_TARE);
		
		if(showReportName.size() == 0 ) return;
		
		tv_content.setText("");
		
		listItem = readValueFromSettings(mNetWorkSettingService.FindAll());
		if (listItem.size() == 0 || listItem == null) {
			MessageBox.show(NetworkReportActivity.this, "Network Setting is empty.");
		} else {
			mNetworkStationDialog = new NetworkStationDialog(NetworkReportActivity.this, NetworkReportActivity.this, listItem);
			mNetworkStationDialog.show();
			mNetworkStationDialog.setState(NetworkStationDialog.FREE);
		}
	}

	private OnClickMessageListener onClickMessageListener = new OnClickMessageListener() {

		public void onClickYes() {
			finish();
		}

		public void onClickNo() {

		}

		public void onClickOK() {

		}
	};
	
	@Override
	public void onCloseWithReturn(Class<? extends MoleQBaseDialog> pramClass, int viewId, String parm) {
		super.onCloseWithReturn(pramClass, viewId, parm);
		
		switch (viewId) {
		case R.id.et_startDate:
			et_startDate.setText(parm);
			startDate = MoleQUtil.fixDateTime2(String.valueOf(et_startDate.getText()), "yyyyMMdd", "yyyy-MM-dd");
			endDate = MoleQUtil.fixDateTime2(String.valueOf(et_startDate.getText()), "yyyyMMdd", "yyyy-MM-dd");
			break;
		default:
			break;
		}
	}
}
